<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--  -->
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="Author" content="Venkita Subramonian">
   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
   <title>RTCORBA 1.0 Scheduling Service</title>
</head>
<body>

<center>
<h2>
RTCORBA 1.0 Scheduling Service</h2></center>

<p><br>Matt Murphy &lt;murphym@cs.uri.edu>
<br>University of Rhode Island
<p>This is an implementation of the RTCORBA 1.0 Scheduling Service. Per
section 3 of the RTCORBA 1.0 specification (OMG), the scheduling service
is comprised of two local interfaces, a ClientScheduler and a ServerScheduler.
<br>&nbsp;
<h3>
Build Issues:</h3>
Run tao_idl -I $TAO_ROOT/ RTCosScheduling.pidl. 
Run make -f Makefile.RTCosScheduling from ../
<br>&nbsp;
<h3>
Synopsis:</h3>
The RTCosScheduler allows clients to schedule tasks according to scheduling
information determined a priori.&nbsp; This scheduling information is stored
in a config file so that both the client and the server has access to it.&nbsp;
(If the client and server exists on different nodes then place a copy of
the config file on each node.)
<p>Per the RTCORBA 1.0 spec, clients use a ClientScheduler object and servers
use a ServerScheduler object to schedule activities on the system.&nbsp;
Since each may or may not use its scheduler, there are four possible scenarios
in which the system may run.&nbsp; These are:
<p>1. Client uses ClientScheduler, Server uses ServerScheduler.&nbsp; In
this case the system follows the rules set forth in the "Scheduling Service"
section of this document below.
<p>2. Client uses ClientScheduler, Server does not use ServerScheduler.
In this case activities are scheduled on the client and run at the mapped
Real Time priority set forth in the config&nbsp; file while executing on
the client.&nbsp; However, any activity on the server does not run at a
real time priority.&nbsp; This means that Multiprocessor Priority Ceiling
Protocol does not manage activities on the server.&nbsp; Currently, the
client has no way of knowing that activity on the server did not follow
the MPCP protocol.&nbsp; Future enhancements to the RTCORBA 1.0 scheduling
service should notify the client (perhaps through a flag to a client interceptor)
that&nbsp;&nbsp; the server did not use MPCP.&nbsp; Please note that this
scenario is generally&nbsp; not recommended as there is a strong possibility
for&nbsp; priority inversion or unexpected blocking in this situation since
any and all server activity that uses the ServerScheduler&nbsp; will run
at a higher priority that server activity that does not.&nbsp;&nbsp; Use
scenario 1 above.&nbsp; Here, the server's priority lowers from&nbsp; RTCORBA::maxPriority
to RTCORBA::minPriority and things will&nbsp; execute on a best effort
basis.
<p>3. Client does not use ClientScheduler, Server uses ServerScheduler.&nbsp;
In this case the client does not use priorities set forth in the config
file.&nbsp; The ServerScheduler, on the other hand, does use MPCP to schedule
execution on the server.&nbsp; It uses the priority sent to the server
by the client, which is the default priority that the
<br>&nbsp;&nbsp; client ran at (since the client priority was not changed
by schedule_activity().&nbsp; This follows the scenario of the ServerScheduler
set forth below.&nbsp; Please note that it is recommended
that you use
scenario 1, above, instead so that the client sends appropriate priorities
to the server.
<p>4. Client does not use ClientScheduler, server does not use ServerScheduler.&nbsp;
In this case neither the client nor the server take advantage of&nbsp;
the RTCORBA 1.0 Scheduler.
<br>&nbsp;
<h3>
Scheduling Service:</h3>
ClientScheduler:
<br>Clients wishing to use the ClientScheduler to schedule activities
<br>must first create a local ClientScheduler object reference.&nbsp; The
<br>ClientScheduler is declared as:
<p>RTCosScheduling_ClientScheduler_i (
<br>&nbsp;&nbsp; CORBA::ORB_var orb, /// Orb reference
<br>&nbsp;&nbsp; char* node,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
/// Node the client resides on
<br>&nbsp;&nbsp; char* file);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
/// Config file holding scheduling information
<br>&nbsp;
<p>The ClientScheduler constructor parses the config file and populates
an ACE_MAP with the activity/priority associations for the node on which
the client resides.&nbsp; It also constructs a ClientScheduler_Interceptor
that adds a service context the send_request interceptor that contains
the priority the client is running at when the call is made.
<p>Once initialized, calls to the ClientScheduler schedule_activity(const
char * activity_name) method will match the activity_name parameter to
the CORBA priority value in the ACE_Map.&nbsp; It linearly maps CORBA priority
to a local OS priority and sets the local OS priority using RT Current.&nbsp;
If the activity name provided is not valid (i.e. not found in the config
file), a RTCosScheduling::UnknownName exception is thrown.
<p>The ClientScheduler also registers an client side interceptor with the
orb.&nbsp; This ClientScheduler_Interceptor finds the CORBA priority that
the client is running at when the remote method call is made and adds this
priority to a service context for the ServerScheduler_Interceptor to use.&nbsp;
Initial tests find that this interceptor adds 0.00015 seconds of execution
on an Intel 3.0 GHz processor.
<br>&nbsp;
<h3>
ServerScheduler:</h3>
Servers that contain local objects that will accept CORBA calls must create
a local ServerScheduler object.&nbsp; The ServerScheduler uses TAO's PortableInterceptors
to intercept incoming client requests and schedule execution on the server.&nbsp;
These interceptors are registered by the ORB_Core as explained in the create_POA
method below. The ServerScheduler is defined as:
<p>&nbsp; RTCosScheduling_ServerScheduler_i (
<br>&nbsp;&nbsp;&nbsp; char *node,&nbsp;&nbsp;&nbsp; /// Node the ServerScheduler
resides on
<br>&nbsp;&nbsp;&nbsp; char *file,&nbsp;&nbsp;&nbsp; /// Config file holding
scheduling information
<br>&nbsp;&nbsp;&nbsp; char *shared_file,&nbsp; /// File used for shared
memory
<br>&nbsp;&nbsp;&nbsp; int numthreads);&nbsp;&nbsp; /// Number of threads
to create in the threadpool
<p>During initialization, the ServerScheduler finds the appropriate node
information in the config file and stores resources (key) on the node and
the appropriate priority ceiling (value) in a map.&nbsp; It also reads
in the base priority for the resource.
<p>The ServerScheduler constructor then registers the PortableInterceptors
necessary to scheduler execution on the server.&nbsp; It also set up the
linear mapping policy and a reference to the RT Current object, both of
which are used for adjusting the server's local OS priority when using
the priority ceiling control protocol.
<p>Once the ServerScheduler object is constructed, users may create an
orb and establish any non real time POA policies they wish to install by
calling the ServerScheduler's create_POA method.
<p>ServerScheduler's create_POA method creates a real time POA that will
set and enforce all non-real time policies.&nbsp; This method also sets
the real time POA to enforce the Server Declared Priority Model Policy
and creates a threadpool responsible for executing calls to the server.
Server Declared Priority Model is used so that the server threads may run
at a high enough priority to intercept requests as soon as they come in.
If Client Propagated Priority Ceilings were used, incoming requests would
not be intercepted until all existing servant execution is completed.&nbsp;
This is because MPCP elevates the priority of servant execution to be higher
than the client priorities.
<p>Recall that the number of threads in the threadpool was supplied by
the ServerScheduler constructor.&nbsp; The create_POA method is defined
as:
<p>&nbsp; virtual ::PortableServer::POA_ptr create_POA (
<br>&nbsp;&nbsp;&nbsp; PortableServer::POA_ptr parent,&nbsp;&nbsp;&nbsp;
/// Non RT POA parent
<br>&nbsp;&nbsp;&nbsp; const char * adapter_name,&nbsp;&nbsp;&nbsp; ///
Name for the POA
<br>&nbsp;&nbsp;&nbsp; PortableServer::POAManager_ptr a_POAManager,&nbsp;
/// Manager for the POA
<br>&nbsp;&nbsp;&nbsp; const CORBA::PolicyList &amp; policies&nbsp; ///
List of non RT policies
<br>&nbsp;&nbsp;&nbsp; ACE_ENV_ARG_DECL)
<br>&nbsp; ACE_THROW_SPEC ((
<br>&nbsp;&nbsp;&nbsp; CORBA::SystemException
<br>&nbsp;&nbsp;&nbsp; , PortableServer::POA::AdapterAlreadyExists
<br>&nbsp;&nbsp;&nbsp; , PortableServer::POA::InvalidPolicy
<br>&nbsp; ));
<br>&nbsp;
<p>Once a RT POA has been created, schedule_object is called to store CORBA
Object references (key) with a name (value) in an ACE_MAP.&nbsp; An
<br>RTCosScheduling::UnknownName exception is thrown if the schedule_object
name parameter is not found in the resource map (i.e. it was not in the
<br>config file.) The schedule_object method is declared as:
<p>&nbsp; virtual void schedule_object (
<br>&nbsp;&nbsp;&nbsp; CORBA::Object_ptr obj,&nbsp; /// A CORBA object
reference
<br>&nbsp;&nbsp;&nbsp; const char * name&nbsp;&nbsp;&nbsp; /// Name to
associate with obj
<br>&nbsp;&nbsp;&nbsp; ACE_ENV_ARG_DECL)
<br>&nbsp; ACE_THROW_SPEC ((
<br>&nbsp;&nbsp;&nbsp; CORBA::SystemException
<br>&nbsp;&nbsp;&nbsp; , RTCosScheduling::UnknownName
<br>&nbsp; ));
<br>&nbsp;
<p>Once all objects that will receive client requests have been scheduled
using schedule_object, clients are free to make calls on those objects.
The scheduling service interceptors catch these calls and perform the necessary
priority ceiling control measures to ensure that the calls are executed
in the appropriate order.&nbsp; The ServerScheduler_Interceptor receive_request
method intercepts all incoming request immediately since it is set to run
at RTCORBA::maxPriority (the highest priority on the server OS).&nbsp;
It then gets the client priority sent in the service context as well as
the resource ceiling for the object and the base priority for the server.
<br>Initial tests indicate that the receive_request interceptor takes around
0.002 seconds to complete on an Intel 3.0 GHz processor.
<p>Given these values it is able to use the Multiprocessor Priority Ceiling
Protocol to schedule execution on the server to handle the request.&nbsp;
MPCP schedules all global critical sections at a higher priority than tasks
on the local processor by adding the client priority to the base priority
of the servant, then adding the resource ceiling of the resource to the
base priority to find the appropriate priority ceiling. For more information
about MPCP, please refer to the book "Real Time Systems", By Jane Liu (2000).
<p>Please not that the locking mechanisms are stored in shared memory on
the server.&nbsp; This means that the locks cannot be stored in linked
lists and are therefore manipulated using memory offsets.&nbsp; The total
number of locks that may be stored in shared memory is currently set at
1024.
<p>When remote execution is complete the send_reply interceptor resets
the thread to listen at RTCORBA::maxPriority and removes the task form
the Invocation
<br>list.&nbsp; Initial test indicate that the send_reply interceptor takes
0.000075 seconds to complete on an Intel 3.0 GHz processor.
<br>&nbsp;
<h3>
Scheduling Service Config File:</h3>
The scheduling service config file holds the information necessary to schedule
the system.&nbsp; Task and resource ceiling information is stored for each
of the nodes as follows:
<p>Node 1&nbsp;&nbsp;&nbsp; /// The node name is 1
<p>Resources:
<br>BP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6000&nbsp; /// The base priority for
the resource
<br>Server1 1000&nbsp;&nbsp; /// A list of resources and their priority
ceiling
<br>Server2 2000
<br>END&nbsp;&nbsp;&nbsp; /// The end of the resource list
<p>Tasks:&nbsp;&nbsp;&nbsp; /// A list of tasks that will execute on the
node
<br>Client1 1000
<br>Client2 3000
<br>Client3 5000
<br>END&nbsp;&nbsp;&nbsp; /// The end of the task list.
<p>Please note that these associations are tab delimited.&nbsp; Please
do not include comments in the scheduling service config file.&nbsp; The
priorities associated
<br>with each task and resource are considered to be CORBA priorities,
and will be mapped to local OS level priorities using the Linear Mapping
<br>model.&nbsp; Per the OMG RT CORBA spec, CORBA priorities have a valid
range up to 32767, where a larger value indicates a higher priority.&nbsp;
The current
<br>config file assumes that the Multiprocessor Priority Ceiling Protocol
is used.
<br>&nbsp;
<h3>
Known Issues:</h3>
TAO does not currently support request buffering, and there are no immediate
plans to do so.&nbsp; Consequently, the RT CORBA 1.0 Scheduling Service
is
<br>limited in that it will only function properly in systems that do not
require request buffering on the servant side.
<p>There is a bug in TAO in which mapped priorities are mapped a second
time when using Client Propagated Priority Ceiling Protocol.&nbsp; This
in effect
<br>lowers the priority that the servant receives.&nbsp; This happens to
each priority, so there should be no effect on the system.
<p>The config file assumes CORBA priorities in the range of 0 to 32767.
The Linear Priority Mapping Manager will map these to valid local OS priorities.&nbsp;
Take care though, in determining the priority range in the config file,
as low numbers or numbers very close in value may produce priority inversion
and other issues.&nbsp; For example, if the CORBA priorities used for three
tasks are 100 200 300, these will all map to OS priority 1 in on some real
time Linux systems. Please take this into
<br>account when determining the CORBA priority range to use.
<p>The 1.0 Scheduling service currently works with one orb and one POA.
If someone tries to install more than one scheduling service (client or
server side) on a single POA, then it should not add a second interceptor.&nbsp;
Please use a single scheduling service per POA.&nbsp; Furthermore, there
is a bug when more than one orb is created, an invalid policy exception
is thrown during the second call to create_POA.&nbsp; This bug is actively
being investigated.&nbsp; In the meantime please use the scheduling service
with one ORB.
<br>&nbsp;
<h3>
Future Enhancements:</h3>
ACE_XML
<br>The current RT CORBA 1.0 Scheduling Service uses a private method to
read the config file.&nbsp; This will soon be replaced with a new XML based
config
<br>file using ACE_XML to parse the config file.
<p>Priority Lanes
<br>Although not currently implemented, Priority Lanes and Thread Borrowing
may increase performance as they would help to prevent lower priority tasks
from exhausting all threads.&nbsp; This is considered a possible future
enhancement.
<p>Client Interceptor
<br>A client interceptor that sends a flag to notify the server interceptor
if schedule_activity() was used to set the client priority.&nbsp; If schedule_activity()
was not used, then the server should probably not try and schedule server
execution using MPCP.&nbsp; Doing so adds competition to other method calls
by other client requests that were scheduled with schedule_activity().
<br>&nbsp;
<h3>
References</h3>
The Object Management Group, Real Time CORBA 1.0 Specification, www.omg.org
<br>Liu, Jane, Real Time Systems, Prentice Hall, 2000
<br>&nbsp;
</body>
</html>
